home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / mpwtools.cpt / misc src / uuencode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-17  |  6.2 KB  |  311 lines

  1. /* Original by Pete Gontier
  2.    Hacked to work as MPW tool by Sak Wathanasin
  3.     # Build an MPW tool
  4.     C -d MPW uuencode.c ╖╖ "{Worksheet}"
  5.     Link -w -o uuencode -t MPST -c "MPS " uuencode.c.o ╢
  6.         "{CLibraries}"StdCLib.o ╢
  7.         "{Libraries}"ToolLibs.o ╢
  8.         "{Libraries}"Runtime.o ╢
  9.         "{Libraries}"Interface.o ╖╖ "{Worksheet}"
  10.     delete uuencode.c.o ╖╖ "{Worksheet}"
  11. */
  12.  
  13. #ifdef    MPW
  14. #include <Types.h>
  15. #include <StdDef.h>
  16. #include <Files.h>
  17. #include <CursorCtl.h>
  18. #include <StdLib.h>
  19. #endif    MPW
  20. #include <errno.h>
  21. #include <stdio.h>
  22. #include <String.h>
  23. #ifndef NIL
  24. #define NIL    (0L)
  25. #endif
  26.  
  27. /* Strings used in error messages */
  28. #ifdef    MPW
  29. #define    CPSTR        c2pstr
  30. #define PCSTR        p2cstr
  31. #else
  32. #define CPSTR        CtoPstr
  33. #define PCSTR        PtoCstr
  34. #endif
  35.  
  36. #ifndef EOF
  37. #define EOF    (-1L)
  38. #endif
  39.  
  40. Boolean unix      = false;          /* convert CR<->LF for Unix */
  41. Boolean    decodeIt  = false;            /* assume encode */
  42. OSType    fdCreator =    '????';            /* Finder Creator */
  43. OSType    fdType      =    '????';            /* Finder Type */
  44.  
  45. /* error codes */
  46.  
  47. #define OTHER    -1    /* something strange happened */
  48. #define NOERR    0    /* everything's hunky-dory */
  49. #define NOOPIN    1    /* opening input file */
  50. #define NOOPOUT    2    /* opening output file */
  51. #define NOREAD    3    /* reading input */
  52. #define NOWRITE    4    /* writing output */
  53. #define    NOCLIN    5    /* closing input */ 
  54. #define NOCLOUT    6    /* closing output */
  55. #define FORMAT    7    /* file is in an unreadable format */
  56. #define UEOF    8    /* unexpected end-of-file */
  57. #define DETRANS    9    /* decompression or translation error */
  58.  
  59. int uudecode ( char *source );
  60. int uuencode ( char *source );
  61.  
  62. int fr ( FILE *fd, char *buf, int cnt );
  63. int decode ( FILE *in, FILE *out );
  64. int doutdec(char *p, FILE *f, int n);
  65. char *index ( char *sp, char c );
  66. int encode( FILE *in, FILE *out);
  67. int eoutdec ( char *p, FILE *f);
  68.  
  69. int fr ( FILE *fd, char *buf, int cnt ) {
  70.     int c, i;
  71.  
  72.     for (i=0; i<cnt; i++) {
  73.         c = getc(fd);
  74.         if (c == EOF)
  75.             return(i);
  76.         buf[i] = c;
  77.     }
  78.     return (cnt);
  79. }
  80.  
  81. /************************************************************************/
  82.  
  83. /* single character decode */
  84. #define DEC(c)    (((c) - ' ') & 077)
  85.  
  86. int uudecode ( char *source ) {
  87.     FILE *in, *out;
  88.     int mode, result;
  89.     char dest[31], buf[80];
  90.  
  91.     if (source == NULL ||
  92.         *source == '-' )
  93.         in = stdin;
  94.     else
  95.         if ( ( in = fopen ( source,  "r" ) ) == NULL )
  96.             return ( NOOPIN );
  97.  
  98.     /* search for header line */
  99.     for (;;) {
  100.         if (fgets(buf, sizeof buf, in) == NULL)
  101.             return ( FORMAT );
  102.         if (strncmp(buf, "begin ", 6) == 0)
  103.             break;
  104.     }
  105.     sscanf(buf, "begin %o %s", &mode, dest);
  106.  
  107.     /* create output file */
  108.     if (*dest == '-' || in == stdin)
  109.         out = stdout;
  110.     else
  111.         out = fopen(dest, (unix? "w" : "wb"));
  112.     if (out == NULL)
  113.         return ( NOOPOUT );
  114.  
  115.     if ( result = decode (in, out) )
  116.         return ( result );
  117.  
  118.     if (fgets(buf, sizeof buf, in) == NULL || strcmp(buf, "end\n"))
  119.         return ( DETRANS );
  120.  
  121.     /* set the file type before we exit */
  122.     fsetfileinfo(dest, fdCreator, fdType);
  123.     return ( NOERR );
  124. }
  125.  
  126. int decode ( FILE *in, FILE *out ) {
  127.     char buf[80];
  128.     char *bp;
  129.     int n, result;
  130.  
  131.     for (;;) {
  132.         /* for each input line */
  133.         SpinCursor(-1);
  134.         if (fgets(buf, sizeof buf, in) == NULL)
  135.             return ( NOREAD );
  136.         n = DEC(buf[0]);
  137.         if (n <= 0)
  138.             break;
  139.  
  140.         bp = &buf[1];
  141.         while (n > 0) {
  142.             if ( result = doutdec(bp, out, n) )
  143.                 return ( result );
  144.             bp += 4;
  145.             n -= 3;
  146.         }
  147.     }
  148.     return ( NOERR );
  149. }
  150.  
  151. int doutdec(char *p, FILE *f, int n) {
  152.     char c1, c2, c3;
  153.  
  154.     c1 = DEC(*p)   << 2 | DEC(p[1]) >> 4;
  155.     c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
  156.     c3 = DEC(p[2]) << 6 | DEC(p[3]);
  157.     if (n >= 1) {
  158.         if (unix && c1 == '\r') c1 = '\n';
  159.         if ( EOF == putc(c1, f) )
  160.             return ( NOWRITE );
  161.     }
  162.     if (n >= 2) {
  163.         if (unix && c2 == '\r') c2 = '\n';
  164.         if ( EOF == putc(c2, f) )
  165.             return ( NOWRITE );
  166.     }
  167.     if (n >= 3) {
  168.         if (unix && c3 == '\r') c3 = '\n';
  169.         if ( EOF == putc(c3, f) )
  170.             return ( NOWRITE );
  171.     }
  172.     return ( NOERR );
  173. }
  174.  
  175. char *index ( char *sp, char c ) {
  176.     do {
  177.         if (*sp == c)
  178.             return(sp);
  179.     } while (*sp++);
  180.     return(NULL);
  181. }
  182.  
  183. /**********************************************************************/
  184.  
  185. /* ENC is the basic 1 character encoding function to make a char printing */
  186. #define ENC(c) (((c) & 077) + ' ')
  187.  
  188. int uuencode (char *source) {
  189.     FILE *in, *out;
  190.     int result;
  191.  
  192.     if (source == NULL ||
  193.         *source == '-' ) {
  194.         in = stdin;
  195.         source = "-";
  196.     }
  197.     else
  198.         if ( ( in = fopen ( source,  "r" ) ) == NULL )
  199.             return ( NOOPIN );
  200.  
  201.     out = stdout;
  202.  
  203.     if (*source == 'ñ') source = "-";
  204.     fprintf(out, "begin %o %s\n", 022, source);
  205.     if ( ferror ( out ) )
  206.         return ( NOWRITE );
  207.  
  208.     if ( NOERR != ( result = encode(in, out) ) )
  209.         return ( result );
  210.  
  211.     fprintf(out, "end\n");
  212.     if ( ferror ( out ) )
  213.         return ( NOWRITE );
  214.     
  215.     return ( NOERR );
  216. }
  217.  
  218. int encode( FILE *in, FILE *out) {
  219.     char buf[80];
  220.     int i, n, result;
  221.  
  222.     for (;;) {
  223.         /* 1 (up to) 45 character line */
  224.         SpinCursor(-1);
  225.         n = fr(in, buf, 45);
  226.         if (unix) {
  227.             /* convert CR->LFs */
  228.             for (i = 0; i < n; i++)
  229.                 if ( *(buf + i) == '\n' )
  230.                     *(buf + i) = '\r';
  231.         }
  232.         if ( EOF == putc(ENC(n), out) )
  233.             return ( NOWRITE );
  234.  
  235.         for (i=0; i<n; i += 3)
  236.             if ( NOERR != ( result = eoutdec(&buf[i], out) ) )
  237.                 return ( result );
  238.  
  239.         if ( EOF == putc('\n', out) )
  240.             return ( NOWRITE );
  241.         if (n <= 0)
  242.             break;
  243.     }
  244.     return ( NOERR );
  245. }
  246.  
  247. int eoutdec ( char *p, FILE *f) {
  248.     int c1, c2, c3, c4;
  249.  
  250.     c1 = *p >> 2;
  251.     c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
  252.     c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
  253.     c4 = p[2] & 077;
  254.     if ( EOF == putc(ENC(c1), f) )
  255.         return ( NOWRITE );
  256.     if ( EOF == putc(ENC(c2), f) )
  257.         return ( NOWRITE );
  258.     if ( EOF == putc(ENC(c3), f) )
  259.         return ( NOWRITE );
  260.     if ( EOF == putc(ENC(c4), f) )
  261.         return ( NOWRITE );
  262.     return ( NOERR );
  263. }
  264.  
  265. main(int argc, char** argv) 
  266. {
  267.     char*    theFile = NULL;
  268. #ifdef    MPW
  269.     InitCursorCtl(nil);
  270. #endif    MPW
  271.     argc--; argv++;
  272.  
  273.     while (argc) {
  274.         if (argv[0][0] == '-') {
  275.             switch (argv[0][1]) {
  276.             case '\0':
  277.                 theFile = "-";
  278.                 break;
  279.             case 'c':
  280.                 /* creator is in next arg */
  281.                 argc--;
  282.                 argv++;
  283.                 strncpy((char *)&fdCreator, argv[0], (size_t)4);
  284.                 break;
  285.             case 't':
  286.                 /* type is in next arg */
  287.                 argc--;
  288.                 argv++;
  289.                 strncpy((char *)&fdType, argv[0], (size_t)4);
  290.                 break;
  291.             case 'u':
  292.                 unix = true;
  293.                 break;
  294.             case 'd':
  295.                 decodeIt = true;
  296.                 break;
  297.             default:
  298.                 fprintf(stderr, "### Usage: uuencode [-d [-u] [-c creator] [-t type]] [file|-]\n");
  299.                 exit(-1);
  300.             }
  301.         }
  302.         else
  303.             theFile = argv[0];
  304.         argc--; argv++;
  305.     }
  306.     if (decodeIt)
  307.         uudecode(theFile);
  308.     else
  309.         uuencode(theFile);
  310. }
  311.